home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / dir / RCS / readdir.c,v < prev    next >
Text File  |  1989-12-11  |  4KB  |  255 lines

  1. head     1.5;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.5
  10. date     89.12.11.13.43.50;  author rab;  state Exp;
  11. branches ;
  12. next     1.4;
  13.  
  14. 1.4
  15. date     89.08.29.15.25.07;  author rab;  state Exp;
  16. branches ;
  17. next     1.3;
  18.  
  19. 1.3
  20. date     89.08.29.14.33.06;  author nelson;  state Exp;
  21. branches ;
  22. next     1.2;
  23.  
  24. 1.2
  25. date     89.04.03.15.48.44;  author mendel;  state Exp;
  26. branches ;
  27. next     1.1;
  28.  
  29. 1.1
  30. date     88.06.26.15.45.58;  author ouster;  state Exp;
  31. branches ;
  32. next     ;
  33.  
  34.  
  35. desc
  36. @@
  37.  
  38.  
  39. 1.5
  40. log
  41. @Fixed byteorder problems.
  42. @
  43. text
  44. @/*
  45.  * Copyright (c) 1983 Regents of the University of California.
  46.  * All rights reserved.  The Berkeley software License Agreement
  47.  * specifies the terms and conditions for redistribution.
  48.  */
  49.  
  50. #if defined(LIBC_SCCS) && !defined(lint)
  51. static char sccsid[] = "@@(#)readdir.c    5.2 (Berkeley) 3/9/86";
  52. #endif
  53.  
  54. #include <stddef.h>
  55. #include <assert.h>
  56.  
  57. #include <sys/param.h>
  58. #include <sys/dir.h>
  59.  
  60. static long swapLong();
  61. static short swapShort();
  62.  
  63. /*
  64.  * get next entry in a directory.
  65.  */
  66. struct direct *
  67. readdir(dirp)
  68.     register DIR *dirp;
  69. {
  70.     register struct direct *dp;
  71.  
  72.     for (;;) {
  73.     if (dirp->dd_loc == 0) {
  74.         dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, 
  75.         DIRBLKSIZ);
  76.         if (dirp->dd_size <= 0) {
  77.         return NULL;
  78.         }
  79.     }
  80.     if (dirp->dd_loc >= dirp->dd_size) {
  81.         dirp->dd_loc = 0;
  82.         continue;
  83.     }
  84.     dp = (struct direct *)(dirp->dd_buf + dirp->dd_loc);
  85.  
  86.     /*
  87.      * Filesystems on big-endian and little-endian systems
  88.      * store the information in the directory in different
  89.      * byte order.  It is kind of tricky to detect which
  90.      * byte order this directory uses.  The record length
  91.      * (d_reclen) must be at least 8 (the offset of d_name
  92.      * in the direct structure) and can not be more than
  93.      * 512 (DIRBLKSIZ).  None of the numbers in the set [8-512]
  94.      * map back onto the same set under byte-swapping, so this
  95.      * is a reliable way of checking.
  96.      */
  97.     if ((unsigned) dp->d_reclen > DIRBLKSIZ ||
  98.         (unsigned) dp->d_reclen < offsetof(struct direct, d_name[0])) {
  99.  
  100.         /*
  101.          * Try byte swapping this entry.
  102.          */
  103.         dp->d_ino = swapLong(dp->d_ino);
  104.         dp->d_reclen = swapShort(dp->d_reclen);
  105.         dp->d_namlen = swapShort(dp->d_namlen);
  106.     }
  107.     if (dp->d_reclen == 0 || dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc) {
  108.         return NULL;
  109.     }
  110.     dirp->dd_loc += dp->d_reclen;
  111.     if (dp->d_ino != 0) {
  112.         assert(dp->d_namlen <= MAXNAMLEN);
  113.         return dp;
  114.     }
  115.     }
  116. }
  117.  
  118. static long
  119. swapLong(x)
  120.     long x;
  121. {        
  122.     union {
  123.     long l;
  124.     char c[4];
  125.     } in, out;
  126.  
  127.     in.l = x;
  128.     out.c[0] = in.c[3];
  129.     out.c[1] = in.c[2];
  130.     out.c[2] = in.c[1];
  131.     out.c[3] = in.c[0];
  132.     return out.l;
  133. }
  134.  
  135. static short
  136. swapShort(x)
  137.     short x;
  138. {
  139.     union {
  140.     short s;
  141.     char c[2];
  142.     } in, out;
  143.  
  144.     in.s = x;
  145.     out.c[0] = in.c[1];
  146.     out.c[1] = in.c[0];
  147.     return out.s;
  148. }
  149.  
  150. @
  151.  
  152.  
  153. 1.4
  154. log
  155. @Byte order stuff wasn't working right.  It needs to swap anytime
  156. the byte order is wrong, not just when it is little endian.
  157. @
  158. text
  159. @d11 3
  160. a15 1
  161. #include <assert.h>
  162. a41 1
  163.     if ((unsigned)dp->d_namlen > MAXNAMLEN) {
  164. d43 14
  165. d64 1
  166. a64 2
  167.     assert(dp->d_namlen <= MAXNAMLEN);
  168.     if (dp->d_reclen <= 0 || dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc) {
  169. d69 1
  170. a73 1
  171.  
  172. @
  173.  
  174.  
  175. 1.3
  176. log
  177. @Added byte swapping stuff.
  178. @
  179. text
  180. @d9 1
  181. a9 1
  182. #endif LIBC_SCCS and not lint
  183. d13 4
  184. a17 3
  185. #if defined(spur) || defined(mips)
  186. #include <netinet/in.h>
  187. #endif
  188. d23 1
  189. a23 1
  190.     register DIR *dirp;
  191. d25 16
  192. a40 1
  193.     register struct direct *dp;
  194. d42 10
  195. a51 27
  196.     for (;;) {
  197.         if (dirp->dd_loc == 0) {
  198.             dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, 
  199.                 DIRBLKSIZ);
  200.             if (dirp->dd_size <= 0)
  201.                 return NULL;
  202.         }
  203.         if (dirp->dd_loc >= dirp->dd_size) {
  204.             dirp->dd_loc = 0;
  205.             continue;
  206.         }
  207.         dp = (struct direct *)(dirp->dd_buf + dirp->dd_loc);
  208.         if ((unsigned)dp->d_namlen > MAXNAMLEN) {
  209.             /*
  210.              * Try byte swapping this entry.
  211.              */
  212.             dp->d_ino = ntohl(dp->d_ino);
  213.             dp->d_reclen = ntohs(dp->d_reclen);
  214.             dp->d_namlen = ntohs(dp->d_namlen);
  215.         }
  216.         if (dp->d_reclen <= 0 ||
  217.             dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc)
  218.             return NULL;
  219.         dirp->dd_loc += dp->d_reclen;
  220.         if (dp->d_ino == 0)
  221.             continue;
  222.         return (dp);
  223. d53 38
  224. d92 1
  225. @
  226.  
  227.  
  228. 1.2
  229. log
  230. @Patch for byte swapping directories on diskless spurs server by sun file
  231. servers.
  232. @
  233. text
  234. @d14 1
  235. a14 1
  236. #ifdef spur
  237. d38 8
  238. a45 5
  239. #ifdef spur
  240.         dp->d_ino = ntohl(dp->d_ino);
  241.         dp->d_reclen = ntohs(dp->d_reclen);
  242.         dp->d_namlen = ntohs(dp->d_namlen);
  243. #endif
  244. @
  245.  
  246.  
  247. 1.1
  248. log
  249. @Initial revision
  250. @
  251. text
  252. @d14 3
  253. d38 5
  254. @
  255.